<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>粒子背景效果</title>
    <style>
        .login-lz {
            height: 100vh;
            overflow: hidden;
        }
        #canvas{
            background-color: #222;
        }
    </style>
</head>
<body>
    <div class="login-lz">
        <canvas id="canvas"></canvas>
    </div>
</body>

<script>
    const canvas=document.getElementById('canvas');
    
    canvas.width=window.innerWidth;
    canvas.height=window.innerHeight;
    const ctx=canvas.getContext('2d');
    class Dot{
        constructor(x,y){
            this.x=x;
            this.y=y;
            // this.dirX=Math.random()*5;
            // this.dirY=Math.random()*5;
            this.dirX=Math.random()*1;
            this.dirY=Math.random()*1;
            this.drawFlag=[];//定义一个空数组，保存已经连线过的点
        }
        draw(){
            ctx.beginPath();
            ctx.fillStyle="rgb(200,200,200)";
            ctx.arc(this.x,this.y,5,0,Math.PI*2);
            ctx.fill();
            ctx.closePath();
        }
        update(){
            // 如果碰到边界，就反方先运动
            if(this.y>canvas.height||this.y<=0){
                this.dirY=-this.dirY;
            }
            if(this.x>canvas.width||this.x<=0){
                this.dirX=-this.dirX;
            }
            this.x+=this.dirX;
            this.y+=this.dirY;
            this.draw();
        }   
    }
    // 定义一个数组存储小球
    const arr=[];
    function init(){
        for(let i=0;i<40;i++){
            let dots=new Dot(Math.random()*canvas.width,Math.random()*canvas.height)
            arr.push(dots);
        }
    }
    init();
    // let dots=new Dot(1,1);
    // dots.draw();
    function animation(){
        // 每次绘画前，清楚原有的轨迹
        ctx.clearRect(0,0,canvas.width,canvas.height);
        requestAnimationFrame(animation);
        arr.forEach((item,index)=>{
            arr.forEach((item1,index1)=>{
                if(index==index1) {
                    return
                }
                if(item1.drawFlag.includes(index)){
                    item1.drawFlag=item1.drawFlag.filter((item)=>{return item!=index});
                    return
                }
                if(Math.abs(item.x-item1.x)<200&&Math.abs(item.y-item1.y)<200){
                    drawLine(item.x,item.y,item1.x,item1.y)
                    // item1.drawFlag.push(index);
                }
            })
            item.update();
        })
    }
    function drawLine(x,y,x1,y1){
        //计算两点距离
        const d=Math.sqrt((x-x1)**2+(y-y1)**2)
        if(d>300){
            return
        }
        ctx.beginPath();
        ctx.strokeStyle=`rgba(200,200,200,${1-d/300})`;
        ctx.moveTo(x,y);
        ctx.lineTo(x1,y1);
        ctx.stroke();
        ctx.closePath();
    }
    animation();
</script>